# 回测引擎测试,从mongo读取数据
# write by hashaki last fix on 2019/01/03
import sys
import os
sys.path.append(os.getcwd())

from hashakisea.engine.backtest.backtestEngine import BacktestingEngine as ha
from hashakisea.engine.backtest.backtestEngine import BacktestingEngine2 as ha2
from hashakisea.strategy.strategy_doubleMA import DoubleMA1Strategy  #TODO:talib有问题，无法加载库，而且没有sma这个指标，这里有一个bug
from hashakisea.engine.analycers.evaluate import Evaluation
from hashakisea.db.feeds.mongoFeed import MongoFeeds,MongoFeed
from datetime import datetime
from queue import Queue

# 单品种的run
def oldMethod():
    a={'base_type':['VnTrader_1Min_Db','IF0000'],'start':'20150105','end':'20150106'} # 旧单品种调用
    print('开始从数据库读数据',datetime.now().strftime('%H:%M:%S'))
    muitiple,bar=MongoFeed.getMongoData(a)
    print('从数据库读完数据',datetime.now().strftime('%H:%M:%S'))

    hashaki=ha()
    hashaki.broker.setCash(10000)
    hashaki.addData(bar,muitiple)
    hashaki.addStrategy(DoubleMA1Strategy,{'n1':1,'n2':2,'fixedSize':1.0})
    print('开始运行回测',datetime.now().strftime('%H:%M:%S'))
    hashaki.run()
    print('回测结束',datetime.now().strftime('%H:%M:%S'))
    #print(len(hashaki.all_close_price))
    #hashaki.plot('echart')

# 多品种的run
def newMethod():
    q=Queue()

    a={'base':{'time':'VnTrader_1Min_Db','base_bars':['IF0000']},'start':'20150105','end':'20150106'}
    print('开始从数据库读数据',datetime.now().strftime('%H:%M:%S'))
    muitiple,kwarg=MongoFeeds.mulMongoData(q,a)
    print('从数据库读完数据',datetime.now().strftime('%H:%M:%S'))

    hashaki=ha2()
    hashaki.broker.setCash(10000)
    hashaki.addMulData(kwarg,muitiple,q)
    hashaki.addStrategy(DoubleMA1Strategy,{'n1':1,'n2':2,'fixedSize':1.0})
    print('开始运行回测',datetime.now().strftime('%H:%M:%S'))
    hashaki.run(mul=True)
    print('回测结束',datetime.now().strftime('%H:%M:%S'))
    print(hashaki.posList)
    #hashaki.plot('echart')

def simulateMethod():
    '''模拟交易测试用例'''
    from hashakisea.api.digital.gateGatewaySimulate import GateGatewaySimulate
    from hashakisea.engine.event.eventEngine import EventEngine
    from hashakisea.engine.simulate.simulateEngine import SimulateEngine
    from hashakisea.strategy.strategyTemplate02 import SrategyTamplateSimulate

    eventEngine=EventEngine()
    gateway=GateGatewaySimulate(eventEngine)
    mainEngine=SimulateEngine(eventEngine)
    mainEngine.addGateway(gateway)
    mainEngine.addStrategy(SrategyTamplateSimulate)
    mainEngine.run()

def turtleMethod():
    '''高仿vnpy海归策略'''
    from datetime import datetime
    import numpy as np
    import matplotlib.pyplot as plt

    from hashakisea.engine.backtest.turtleEngine import BacktestingEngine

    engine = BacktestingEngine()
    engine.setPeriod(datetime(2014, 1, 1), datetime(2018, 12, 30))
    engine.initPortfolio('setting.csv', 10000000)

    engine.loadData()
    engine.runBacktesting()
    engine.showResult()

    tradeList = engine.getTradeData('000300')
    for trade in tradeList:
        print ('%s %s %s %s@%s' %(trade.target_symbol, trade.direction, trade.offset,
                             trade.volume, trade.price))


def downloadBTCKline():
    '''下载24小时比特币K线用于测试回测引擎'''
    from hashakisea.api.digital.gateio import GateIO
    a=GateIO()
    target_symbol_list=['btc_usdt','eos_usdt']
    data={}
    for i in target_symbol_list:
        data_return_from_exchange=a.kLine(i,sec=60,hour=1)
        K_line_data=data_return_from_exchange['data']
        temp=[]
        for j in K_line_data:
            temp.append({'time':j[0],'vloume':float(j[1]),'open':float(j[2]),'high':float(j[3]),'low':float(j[4]),'close':float(j[5])})
        data[i]=temp

    return data

def exchangeDataMultipleMethod():
    print('开始从交易所数据',datetime.now().strftime('%H:%M:%S'))
    data=downloadBTCKline()
    print('从交易所下载完并处理完数据',datetime.now().strftime('%H:%M:%S'))

    q=Queue()
    q.put(data)

    hashaki=ha2()
    hashaki.broker.setCash(10000)
    hashaki.addMulData(None,None,q)
    hashaki.addAnalyzer(Evaluation)
    hashaki.addStrategy(DoubleMA1Strategy,{'n1':1,'n2':2,'fixedSize':1.0})
    print('开始运行回测',datetime.now().strftime('%H:%M:%S'))

    hashaki.run(mul=True)
    print('回测结束',datetime.now().strftime('%H:%M:%S'))
    print(hashaki.posList)
    #hashaki.plot('echart')

def bitQuantDataMethod():
    '''从BitQuant数据库读取数据进行回测，示例
    数据库s:'crypto_12hour', 'crypto_15min', 'crypto_1day', 'crypto_1hour', 'crypto_1min', 'crypto_30min', 'crypto_3hour',
     'crypto_5min', 'crypto_6hour', 'future_15min', 'future_1day', 'future_1hour', 'future_1min', 'future_1month',
      'future_1week', 'future_30min', 'future_5min' '''
    from hashakisea.db.feeds.mongoFeed import MongoFeedFromBitQuant
    q=Queue()
    a={'base':{'time':'crypto_1hour','base_bars':['bitfinex_btc_usd','bitfinex_eos_usd']},'start':'20181006','end':'20181107'}
    print('开始从数据库读取数据',datetime.now().strftime('%H:%M:%S'))
    muitiple,kwarg=MongoFeedFromBitQuant.mulMongoData(q,a)
    print('数据库读取完毕',datetime.now().strftime('%H:%M:%S'))

    hashaki=ha2()
    hashaki.broker.setCash(10000)
    hashaki.addMulData(kwarg,muitiple,q)
    hashaki.addStrategy(DoubleMA1Strategy,{'n1':1,'n2':2,'fixedSize':1.0})
    print('开始运行回测',datetime.now().strftime('%H:%M:%S'))
    hashaki.run(mul=True)
    print('回测结束',datetime.now().strftime('%H:%M:%S'))
    print(hashaki.posList)
    #hashaki.plot('echart')

def connectMarket():
    '''对接交易所接口和做市引擎的逻辑层'''
    from hashakisea.engine.market.marketEngine import MarketEngine
    from hashakisea.api.digital.gateio import GateIO
    from hashakisea.engine.brokers.marketBroker import MarketBroker
    from datetime import datetime
    from collections import defaultdict

    depth=defaultdict(list)
    exchange=GateIO()
    #marketBroker=MarketBroker()
    market=MarketEngine()
    depth_string=exchange.orderBook('btc_usdt')
    
    # 处理成需要的数据
    for ask,bid in zip(depth_string['asks'],depth_string['bids']):
        depth['asks'].append([float(ask[0]),float(ask[1])])
        depth['bids'].append([float(bid[0]),float(bid[1])])
    
    depth['time']=datetime.now()
    
    # 以上都是获取数据处理数据部分
    market.dataIn(depth,depth)                         # 第一个参数为目标交易所的深度数据，第二个参数为对冲交易所的深度数据
    market.judgeSrategy(0.01,0.01)
    market.precentSetting({'ask':0.005,'bid':0.005})
    market.accountSetting(3.0,1.0)
    market.orderDataIn(depth)                          # 目标交易所中我们自己挂单的深度
    market.engineSetting(1,1,0.01)                     # 手续费，滑点，跨市转账的手续费，档位更新阈值
    order_result,cancel_result=market.run()
    print(order_result,cancel_result)                                      # 最终返回应该发什么单

def gateGatewayTest():
    '''测试gateio网关'''
    from hashakisea.api.digital.gateGateway import GateGateway

    a=GateGateway()
    a.start()
    a.run()
    '''
    客户端代码
    import socket               # 导入 socket 模块

    s = socket.socket()         # 创建 socket 对象
    host = socket.gethostname() # 获取本地主机名
    port = 6666               # 设置端口号

    s.connect((host, port))
    while 1:
        print(s.recv(2048))
    '''

def tradeTest():
    '''检测交易引擎'''
    from hashakisea.engine.trade.tradeEngine import MainEngine
    from hashakisea.strategy.haStrategy_test import HaStrategyTest
    
    a=MainEngine()
    a.engingSetting('127.0.0.1',6666)
    a.start()
    s=HaStrategyTest()
    strategy=[{'test_strategy':['depth',s]}]
    a.strategyIn(strategy)
    a.run()

def bigStrategyTest():
    '''包含大策略的测试'''
    from hashakisea.strategy.bigStrategy.haBigStrategy import BigStrategy
    a=BigStrategy()
    a.settingSocket('127.0.0.1',6667)
    a.run()

def check_example(example):
    '''检测案例生成'''
    from humanBehavior.asWorker import AsWorker
    a=AsWorker()
    a.exampleIn(example)
    a.saveExample()

if __name__=='__main__':
    from multiprocessing import Process
    from time import sleep
    get_data_process=Process(target=gateGatewayTest)
    run_trade=Process(target=tradeTest)
    big_strategy=Process(target=bigStrategyTest)
    get_data_process.start()
    sleep(0.5)
    run_trade.start()
    big_strategy.start()

    '''
    name='我把我的工作开源的消息告诉老板的案例'
    content='我有一个开源项目，与公司工作的内容有相关性，被公司老板发现，老板的脸色好难看，开源是一件好事，\
    但涉及到公司的利益就不是一件,开心的事，有可能会因此而被解雇的'

    example={}
    example['name']=name
    example['content']=content
    check_example(example)
    '''